home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / Pascal / Book Demos in Pascal / ScoresDemo / ScoresDemo.p < prev    next >
Text File  |  1995-05-26  |  7KB  |  266 lines

  1. program ScoresDemo;
  2.  
  3.     uses
  4. {$ifc UNDEFINED THINK_PASCAL}
  5.         Types, QuickDraw, Events, Windows, Dialogs, Fonts, DiskInit, TextEdit, Traps,{}
  6.         Memory, SegLoad, Scrap, ToolUtils, OSUtils, Menus, Resources, StandardFile, {}
  7.         GestaltEqu, Files, Errors, Packages, OSEvents, 
  8. {$endc}
  9.         Preferences;
  10.  
  11.  
  12. {***************** A dialog asking for the player's name *****************}
  13.  
  14. {Filter function for AskHigh, ok = 1 and cancel = 2}
  15.     function Filter (theDialog: DialogPtr; var theEvent: EventRecord; var itemHit: integer): Boolean;
  16.         var
  17.             theChar: Char;
  18.             kind: integer;
  19.             item: Handle;
  20.             box: Rect;
  21.     begin
  22.         case theEvent.what of
  23.             keyDown: 
  24.                 begin
  25.                     theChar := Char(BitAnd(theEvent.message, charCodeMask));
  26.                     if ((BitAnd(theEvent.modifiers, cmdkey) <> 0) and (theChar = '.')) or (theChar = char(27)) then {cmd-. or ESC}
  27.                         begin
  28.                             itemHit := 2;
  29. {Highlight the cancel button}
  30.                             GetDItem(theDialog, 2, kind, item, box);
  31.                             HiliteControl(ControlHandle(item), 1);
  32.  
  33.                             Filter := true;
  34.                             exit(Filter);
  35.                         end;
  36.                     if (theChar = char(13)) or (theChar = char(3)) then
  37.                         begin
  38.                             itemHit := 1;
  39. {Highlight the OK button}
  40.                             GetDItem(theDialog, 1, kind, item, box);
  41.                             HiliteControl(ControlHandle(item), 1);
  42.  
  43.                             Filter := true;
  44.                             exit(Filter);
  45.                         end;
  46.                 end; {keyDown}
  47.             updateEvt: 
  48.                 begin
  49.                     BeginUpdate(theDialog);
  50.                     SetPort(theDialog);
  51.  
  52.                     DrawDialog(theDialog);
  53.  
  54. {Frame default button - item 1}
  55.                     GetDItem(theDialog, 1, kind, item, box);
  56.                     InsetRect(box, -4, -4);
  57.                     PenSize(3, 3);
  58.                     FrameRoundRect(box, 15, 15);
  59.  
  60.                     EndUpdate(theDialog);
  61.                 end; {update event}
  62.         end; {case}
  63.         Filter := false;
  64.     end; {Filter}
  65.  
  66.     const
  67.         kHighDlogRes = 128;
  68.  
  69. { Ask for players name (at highscore) }
  70.     function AskHigh: str255;
  71.         var
  72.             dialog: DialogPtr;
  73.             oldPort: GrafPtr;
  74.             itemHit: integer;
  75.             itemHandle: Handle;
  76.             itemType: integer;
  77.             itemRect: Rect;
  78.             str: str255;
  79.     begin
  80.         GetPort(oldPort);
  81.         dialog := GetNewDialog(kHighDlogRes, nil, WindowPtr(-1));
  82.         ShowWindow(dialog);
  83.         SelectWindow(dialog);
  84.         SetPort(dialog);
  85.  
  86.         GetDItem(dialog, 3, itemType, itemHandle, itemRect);
  87.         SetIText(itemHandle, 'Your name here');        {Insert string from the prefs file here}
  88.         SelIText(dialog, 3, 0, 32767);
  89.         itemHit := -1;
  90.         while (itemHit <> 1) and (itemHit <> 2) do { 1=ok, 2=cancel }
  91.             ModalDialog(@Filter, itemHit);
  92.         if itemHit = 2 then
  93.             begin
  94.                 AskHigh := '';
  95.             end;
  96.         if itemHit = 1 then
  97.             begin
  98.                 GetDItem(dialog, 3, itemType, itemHandle, itemRect);
  99.                 GetIText(itemHandle, str);
  100.                 AskHigh := str;
  101.             end;
  102.         CloseDialog(dialog);
  103.         SetPort(oldPort);
  104.     end; {AskHigh}
  105.  
  106.  
  107. {***************** High score handling *****************}
  108.  
  109.  
  110.     const
  111.         kNameLength = 15;
  112.     var
  113.         gLastHigh: Integer;
  114.  
  115. { Highscore record }
  116.     type
  117.         HighScoreRec = record
  118.                 score: array[0..10] of Longint;
  119.                 name: array[0..10] of string[kNameLength];
  120.             end;
  121.         HighScorePtr = ^HighScoreRec;
  122.         HighScoreHnd = ^HighScorePtr;
  123.  
  124.     var
  125.         highScores: HighScoreHnd;
  126.  
  127. { Call this on game over! }
  128.     procedure UpdateHighScore (score: Longint);
  129.         var
  130.             num, len: integer;
  131.             name, s: str255;
  132.     begin
  133.         if score > highScores^^.score[10] then
  134.             begin
  135.                 num := 10;
  136.                 name := AskHigh; {Call some function that asks for the name.}
  137. {Max 15 characters! We take some extra trouble to append '…' too.}
  138.                 if length(name) > kNameLength then
  139.                     name := Concat(Copy(name, 1, kNameLength - 1), '…');
  140.  
  141.                 if name = '' then { alt length(name) = 0 }
  142.                     exit(UpdateHighScore);
  143.                 while (highScores^^.score[num - 1] < score) and (num > 1) do
  144.                     begin
  145.                         highScores^^.score[num] := highScores^^.score[num - 1];
  146.                         highScores^^.name[num] := highScores^^.name[num - 1];
  147.                         num := num - 1;
  148.                     end;
  149.                 gLastHigh := num; {Remember last high for the highscore display}
  150.                 highScores^^.score[num] := score;
  151.                 highScores^^.name[num] := name; {AskHigh;}
  152.                 ChangedResource(Handle(highScores));
  153.             end;
  154.     end;
  155.  
  156.  
  157. {InitScores}
  158. {This procedure loads the high score list from a resource in the current resource file,}
  159. {creating a new one if there is none.}
  160.  
  161.     procedure InitScores;
  162.         var
  163.             i: integer;
  164.             ignoreErr: OSErr;
  165.     begin
  166.         highScores := HighScoreHnd(GetResource('Bäst', 0));
  167.         if highScores = nil then {Didn't exist - create it!}
  168.             begin
  169.                 highScores := HighScoreHnd(NewHandle(Sizeof(HighScoreRec)));
  170.                 if highScores = nil then
  171.                     ExitToShell;                            {Insert error message here}
  172.                 for i := 1 to 10 do
  173.                     begin
  174.                         highScores^^.score[i] := 0;
  175.                         highScores^^.name[i] := 'Nobody';
  176.                     end;
  177.                 highScores^^.score[0] := 10000;            { Lowscore }
  178.                 AddResource(Handle(highScores), 'Bäst', 0, 'High scores');
  179.             end
  180.         else {Did exist - check the size!}
  181.             if GetHandleSize(Handle(highScores)) < sizeof(HighScoreRec) then
  182.                 SetHandleSize(Handle(highScores), sizeof(HighScoreRec));
  183.     end; {InitScores}
  184.  
  185.  
  186. (* Standard inits *)
  187.  
  188.     procedure InitToolbox;
  189.     begin
  190. {$IFC UNDEFINED THINK_PASCAL}
  191.         InitGraf(@qd.thePort);
  192.         InitFonts;
  193.         FlushEvents(everyEvent, 0);
  194.         InitWindows;
  195.         InitMenus;
  196.         TEInit;
  197.         InitDialogs(nil);
  198. {$ENDC}
  199.         InitCursor;
  200.     end;
  201.  
  202.  
  203. {***************** Main program *****************}
  204.  
  205.     var
  206.         myWindow: WindowPtr;
  207.         str: Str255;
  208.         windowRectangle: Rect;
  209.         i: Integer;
  210.         gAppFile, gPrefFile: integer;
  211.  
  212. begin
  213.     InitToolBox;
  214.     
  215. {Get the prefs file - create as necessary.}
  216.     if SetPrefFile('ScoresDemo Preferences', '????', 'pref', gAppFile, gPrefFile) then
  217.         ;
  218.  
  219. {Set the current resource file to the preference file before InitScores}
  220.     if gPrefFile <> 0 then
  221.         UseResFile(gPrefFile);
  222.     InitScores;
  223.     UseResFile(gAppFile);
  224.  
  225. {Let's seed the random number generator so we don't get the same all the time!}
  226. {$ifc UNDEFINED THINK_PASCAL}
  227.     qd.randSeed := TickCount;
  228. {$elsec}
  229.     randSeed := TickCount;
  230. {$endc}
  231.  
  232. {Update the high score list with a random score.}
  233.     UpdateHighScore(abs(Random));
  234.  
  235. {Set up the window}
  236.     SetRect(windowRectangle, 100, 100, 400, 260);
  237.     myWindow := NewCWindow(nil, windowRectangle, 'High scores demo', true, 0, WindowPtr(-1), false, 0);
  238.     SetPort(myWindow);
  239.  
  240.     for i := 1 to 10 do
  241.         begin
  242.  
  243. {We draw the latest high score with red.}
  244.             if i = gLastHigh then
  245.                 ForeColor(redColor)
  246.             else
  247.                 ForeColor(blackColor);
  248.  
  249. {Draw the position number}
  250.             MoveTo(10, 15 * i);
  251.             NumToString(i, str);
  252.             DrawString(str);
  253.  
  254. {Draw the name}
  255.             MoveTo(50, 15 * i);
  256.             DrawString(highScores^^.name[i]);
  257.  
  258. {Draw the score}
  259.             MoveTo(200, 15 * i);
  260.             NumToString(highScores^^.score[i], str);
  261.             DrawString(str);
  262.         end;
  263.  
  264.     while not Button do
  265.         ;
  266. end. {ScoresDemo}